package com.xbongbong.saas.factory.publicrule;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.SizeConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.constant.EsNormalConstant;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.help.subform.TransferSubFormHelper;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CustomerRuleEntity;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.domain.entity.RuleCustomerEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.OpportunityEntityExt;
import com.xbongbong.saas.enums.ChildCustomerRuleEnum;
import com.xbongbong.saas.enums.CustomerRuleChildEnum;
import com.xbongbong.saas.enums.CustomerRuleEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.subform.CustomerTeamEnum;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * 公共方法抽象类
 * @author : chy
 * @date 创建时间：2018-5-23 下午2:12:45
 * @version v3.22
 */
public abstract class AbstractCheckRule {
	private static final Logger LOG = LoggerFactory.getLogger(AbstractCheckRule.class);
	@Resource
    protected ContractModel contractModel;
	@Resource
	protected OpportunityModel opportunityModel;
	@Resource
	protected CustomerUserModel customerUserModel;
	@Resource
	protected XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
	@Resource
	private TransferSubFormHelper transferSubFormHelper;
	@Resource
	private IndexTypeModel indexTypeModel;

	/**
	 * @Description: 移除规则中不需要退回公海池的客户
	 * @param corpid 公司id
	 * @param customerList 客户列表
	 * @param contract 0不做处理，1移除有合同的客户
	 * @param opportunity 0不做处理，1移除有机会的客户
	 * @param typeNotIn 需要移除的客户状态
	 * 创建时间： 2018-5-23 上午10:57:21
	 * 修改时间： 2018-5-23 上午10:57:21 chy
	 * @author chy
	 * @since v3.22
	 * @version v3.22
	 */
	public void removeRuleNoBack(String corpid,
								 List<RuleCustomerEntity> customerList, Integer contract,
								 Integer opportunity, List<String> typeNotIn) {
		List<Long> customerIdIn = new ArrayList<>();
		customerIdIn.add(-1L);
		//移除被规则排除的客户状态
		if(typeNotIn != null){
	        Iterator<RuleCustomerEntity> it = customerList.iterator();
	        while(it.hasNext()) {
				RuleCustomerEntity customer = it.next();
				String type = "";
				Integer typeInt = customer.getType();
				if (typeInt != null) {
					type = customer.getType().toString();
				}
	            if(typeNotIn.contains(type)){
	            	it.remove();
	            }else{
	            	customerIdIn.add(customer.getId());
	            }
	        }
		}
		if(contract != null && Objects.equals(contract, 1)){
            Integer del = 0;
			List<Long> customerIdInContractNoBack = getCustomerIdsFromContract(corpid, customerIdIn, del);
			removeByCustomerIdIn(customerList, customerIdInContractNoBack);
			customerIdIn.removeAll(customerIdInContractNoBack);
		}


		if(opportunity != null && Objects.equals(opportunity, 1)){
            Integer del = 0;
            List<Long> customerIdInOpportunityNoBack = getCustomerIdsFromOpportunity(corpid, customerIdIn, del);
			removeByCustomerIdIn(customerList, customerIdInOpportunityNoBack);
		}
	}


	/**
	 * @Description: 根据标签移除规则中不需要退回公海池的客户
	 * @param customerList 客户列表
	 * @param labelNotIn 需要移除的客户标签
	 */
	public void removeRuleLabelNoBack(List<RuleCustomerEntity> customerList, List<Long> labelNotIn) {
		List<Long> clueIdIn = new ArrayList<>();
		clueIdIn.add(-1L);
		//移除被规则排除的线索标签
		if(CollectionsUtil.isEmpty(labelNotIn)){
			return;
		}
		Iterator<RuleCustomerEntity> it = customerList.iterator();
		while(it.hasNext()) {
			RuleCustomerEntity customer = it.next();
			String labels = customer.getLabels();
			if (StringUtil.isEmpty(labels) || "null".equals(labels)) {
				continue;
			}
			List<Long> labelIds = null;
			try {
				labelIds = JSONArray.parseArray(labels, Long.class);
			}catch (Exception e){
				LOG.error("removeRuleLabelNoBack: 客户标签转换错误",e);
				continue;
			}
			if(labelIds==null){
				continue;
			}
			labelIds.retainAll(labelNotIn);
			if(CollectionsUtil.isNotEmpty(labelIds)){
				it.remove();
			}else{
				clueIdIn.add(customer.getId());
			}
		}
	}


	/**
	 * 获取存在机会的客户id
	 * @param corpid
	 * @param customerIdIn
	 * @param del
	 * @return
	 * 创建时间 2019/3/1 4:05 PM
	 * 修改时间 2019/3/1 4:05 PM
	 * @author chy
	 * @since v1.0
	 * @version v1.0
	 */
    public List<Long> getCustomerIdsFromOpportunity(String corpid, List<Long> customerIdIn, Integer del) {
		List<Long> customerIds = null;
        try {
            Set<Long> customerIdSet = new HashSet<>();
			BoolQueryBuilder boolQueryBuilder = boolQuery();
			boolQueryBuilder
					.filter(termQuery("corpid.keyword", corpid))
					.filter(termQuery("del", del))
					.filter(termsQuery(SalesOpportunityEnum.getEsAttr4Keyword(SalesOpportunityEnum.CUSTOMER_NAME), customerIdIn));
			boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_OPPORTUNITY.getType()));
			SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
			sourceBuilder.query(boolQueryBuilder).fetchSource(new String[]{"data." + SalesOpportunityEnum.CUSTOMER_NAME.getAttr()}, null);
			SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_OPPORTUNITY.getIndex());
			EsUtil.setPage(sourceBuilder, 1, EsNormalConstant.FIND_NUM);
			searchRequest.source(sourceBuilder);
			List<PaasFormDataEntityExt> content  = xbbElasticsearchRestTemplate.findScrollList(PaasFormDataEntityExt.class,searchRequest, SizeConstant.SCROLL_TIME_IN_MILLIS);

            for(PaasFormDataEntityExt paasFormDataEsEntity : content) {
                JSONObject contractDataObject = paasFormDataEsEntity.getData();
                Long customerId = contractDataObject.getLong(SalesOpportunityEnum.CUSTOMER_NAME.getAttr());
                customerIdSet.add(customerId);
            }
            customerIds = new ArrayList<>(customerIdSet);
        } catch (Exception e) {

        }
		return customerIds;
    }

	/**
	 * 获取存在合同的客户id
	 * @param corpid
	 * @param customerIdIn
	 * @param del
	 * @return
	 * 创建时间 2019/3/1 4:04 PM
	 * 修改时间 2019/3/1 4:04 PM
	 * @author chy
	 * @since v1.0
	 * @version v1.0
	 */
	public List<Long> getCustomerIdsFromContract(String corpid, List<Long> customerIdIn, Integer del){
		List<Long> customerIds = null;
		try {
			Set<Long> customerIdSet = new HashSet<>();

			BoolQueryBuilder boolQueryBuilder = boolQuery();
			boolQueryBuilder
					.filter(termQuery("corpid.keyword", corpid))
					.filter(termQuery("del", del))
					.filter(termsQuery(ContractEnum.getEsAttr4Keyword(ContractEnum.LINK_CUSTOMER), customerIdIn));
			boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
			SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
			sourceBuilder.query(boolQueryBuilder).fetchSource(new String[]{"data." + ContractEnum.LINK_CUSTOMER.getAttr()}, null);
			SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
			EsUtil.setPage(sourceBuilder, 1, EsNormalConstant.FIND_NUM);
			searchRequest.source(sourceBuilder);
			List<PaasFormDataEntityExt> content  = xbbElasticsearchRestTemplate.findScrollList(PaasFormDataEntityExt.class,searchRequest, SizeConstant.SCROLL_TIME_IN_MILLIS);

			for(PaasFormDataEntityExt paasFormDataEsEntity : content) {
				JSONObject contractDataObject = paasFormDataEsEntity.getData();
				Long customerId = contractDataObject.getLong(ContractEnum.LINK_CUSTOMER.getAttr());
				customerIdSet.add(customerId);
			}
			customerIds = new ArrayList<>(customerIdSet);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return customerIds;
    }

    private void removeByCustomerIdIn(List<RuleCustomerEntity> customerList,
			List<Long> customerIdIn) {
		Iterator<RuleCustomerEntity> it = customerList.iterator();
        while(it.hasNext()) {
			RuleCustomerEntity customer = it.next();
            if(customerIdIn.contains(customer.getId())){
            	it.remove();
            }
        }
	}

	/**
	 * @Description: 获取  客户id：CustomerUserEntity的一个map
	 * @param corpid 公司id
	 * @param userId 客户所属的员工id
	 * @param customerList 员工所属的客户id
	 * @return
	 * 创建时间： 2018-5-26 下午1:36:47
	 * 修改时间： 2018-5-26 下午1:36:47 chy
	 * @author chy
	 * @since v3.22
	 * @version v3.22
	 */
	public Map<Long, CustomerUserEntity> getCustomerUserMap(String corpid, String userId, List<RuleCustomerEntity> customerList) throws XbbException {
        Long startTime = DateTimeUtil.getInt();
        Map<Long, CustomerUserEntity> retMap = new HashMap<>(16);
		List<Long> customerIdIn = new ArrayList<>();
		for(RuleCustomerEntity customer : customerList){
			customerIdIn.add(customer.getId());
		}
		if (customerIdIn.isEmpty()) {
		    return retMap;
        }
		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
		BoolQueryBuilder filter = boolQuery()
				.filter(termQuery("corpid.keyword", corpid))
				.filter(termsQuery(CustomerTeamEnum.getEsAttr(CustomerTeamEnum.DATA_ID), customerIdIn))
				.filter(termQuery(CustomerTeamEnum.getEsAttr(CustomerTeamEnum.USER_ID), userId))
				.filter(termQuery(CustomerTeamEnum.getEsAttr(CustomerTeamEnum.IS_MAIN), 1))
				.filter(termQuery("del", 0));
		sourceBuilder.sort(CustomerTeamEnum.getEsAttr(CustomerTeamEnum.DISTRIBUTION_TIME), SortOrder.DESC);
		//拿固定数据
		sourceBuilder.fetchSource(new String[]{CustomerTeamEnum.getAttrConnectData(CustomerTeamEnum.DATA_ID),CustomerTeamEnum.getAttrConnectData(CustomerTeamEnum.DISTRIBUTION_TIME)},null);
		IndexTypeEnum customerTeamIndex = indexTypeModel.getCustomerTeamIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

		filter.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, customerTeamIndex.getType()));
		sourceBuilder.query(filter);
		SearchRequest searchRequest = new SearchRequest(customerTeamIndex.getIndex());
		PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, 10000);
		searchRequest.source(sourceBuilder);
		XbbAggregatedPage<PaasFormDataEntity> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest,searchRequest, PaasFormDataEntity.class);
		List<CustomerUserEntity> list =(List<CustomerUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_CUSTOMER_TEAM, esEntities.getContent());


		for(CustomerUserEntity customerUser : list){
			retMap.put(customerUser.getDataId(), customerUser);
		}
        String paramStr = "corpid:" + corpid + "userId:" + userId + "customerIdIn.size:" + customerIdIn.size();
		return retMap;
	}

	/**
	 * @Description: 判断客户分配时间是否超过规则设置的天数
	 * @param customerUser 客户员工分配关系
	 * @param ruleDay 规则设置的天数
	 * @return
	 * 创建时间： 2018-5-26 下午2:06:53
	 * 修改时间： 2018-5-26 下午2:06:53 chy
	 * @author chy
	 * @since v3.22
	 * @version v3.22
	 */
	public boolean distributionTimeExceedRuleTime(CustomerUserEntity customerUser, Integer ruleDay){

		Long second = ruleDay * 86400L;

		//获取客户分配时间
		Long distributionTime = null;
		if(customerUser != null){
			distributionTime = customerUser.getDistributionTime();
		}

		if(distributionTime!=null){
			//捞取客户的时间在规则时间之内
			if((DateTimeUtil.getInt() - distributionTime) < second){
				return false;
			}
		}else{
			//当分配时间是空的时候也不用处理
			return false;
		}
		return true;
	}

	/**
	 * 设置客户退回公海池提醒内容
	 * @param customer 客户实体
	 * @param userName 客户负责人名
	 * @param ruleType 规则类型
	 * @param newTime 最新的客户联系时间、合同签订时间、机会添加时间(也可能是分配时间)
	 * @param day 规则中限制的天数（不算上提前量）
	 * 创建时间： 2018年7月31日 下午2:53:22
	 * 修改时间： 2018年7月31日 下午2:53:22 chy
	 * @author chy
	 * @since v3.26
	 * @version v3.26
	 */
	public void setLeftDay(RuleCustomerEntity customer, String userName, Integer ruleType, Long newTime, Integer day){
		Long leftDay = 0L;

		Long now = DateTimeUtil.getInt();
		//应该退回的时间
		Long backTime = newTime + (day * 86400L);
		//现在到退回时间的时间间隔
		Long leftTime = backTime - now;
		if(leftTime > 0) {
			//正常提醒
			leftDay = leftTime / TimeConstant.SECONDS_PER_DAY;
			if(leftTime % TimeConstant.SECONDS_PER_DAY > 0) {
				leftDay ++;
			}
		}

		String ruleName = CustomerRuleEnum.getByCode(ruleType).getName();
		leftDay = leftDay < 1 ? 1 : leftDay;

		String memo = String.format(I18nMessageUtil.getMessage(StringConstant.PUBLIC_TAG_MEMO), userName, ruleName, leftDay);

		customer.setUserName(userName);
		customer.setRuleName(ruleName);
		customer.setLeftDay(leftDay);
		customer.setNotifyMemo(memo);
	}

	/**
	 * 客户状态改变时，对公海规则 无新建跟进客户规则 无新建机会客户规则 无签订合同客户规则 这三种规则的影响（这三种规则的格式相同）
	 * @param rule
	 * @param typeItemPoJos
	 * @return
	 * @throws XbbException
	 * 创建时间 2018/12/4 2:12 PM
	 * 修改时间 2018/12/4 2:12 PM
	 * @author chy
	 * @since v3.35
	 * @version v3.35
	 */
	public JSONObject customerTypeChageBasic(CustomerRuleEntity rule, List<ItemPoJo> typeItemPoJos) throws XbbException {
		IOperateRuleValue operateRuleValue = OperateRuleValueFactory.operateRuleValueFactory(rule.getRuleType());
		Object ruleValueObject = operateRuleValue.toObject(rule);
		JSONObject ruleValueJson = (JSONObject)ruleValueObject;

		Integer type = ruleValueJson.getInteger("type");
		JSONArray restrict = ruleValueJson.getJSONArray("restrict");
		JSONArray restrictEnd = new JSONArray();

		//当为客户状态设置时需要修改
		if(Objects.equals(type, ChildCustomerRuleEnum.CUSTOMER_STATUS.getCode())){
			//遍历所有相关设置
			for(Object restrictObject : restrict){
				JSONObject restrictJson = (JSONObject)restrictObject;
				JSONArray arrayEnd = new JSONArray();
				JSONArray array = restrictJson.getJSONArray("array");
				for(ItemPoJo itemPoJo : typeItemPoJos){
					Integer value = StringUtil.toInt(String.valueOf(itemPoJo.getValue())) ;
					if(value == null){
						continue ;
					}
					//获取code对应的设置
					JSONObject json = getJsonByCode(array, value);
					//若不存在，设置成默认的值
					if(json == null){
						json = new JSONObject();
						json.put("key", value);
						json.put("value", 14);
					}

					arrayEnd.add(json);

				}
				restrictJson.put("array", arrayEnd);
				restrictEnd.add(restrictJson);
			}
			ruleValueJson.put("restrict", restrictEnd);
		}
		return ruleValueJson;
	}

	/**
	 * 获取code对应的设置
	 * @param array
	 * @param code
	 * @return
	 * 创建时间 2018/12/4 9:46 AM
	 * 修改时间 2018/12/4 9:46 AM
	 * @author chy
	 * @since v3.35
	 * @version v3.35
	 */
	public JSONObject getJsonByCode(JSONArray array, Integer code) {
		for(Object object : array){
			JSONObject json = (JSONObject)object;
			String keyStr = json.getString("key");

			Integer key = StringUtil.toInt(keyStr, null);

			if(Objects.equals(key, code)){
				return json;
			}
		}
		return null;
	}

    /**
     * @Description: 获取最小公海规则配置
     * @param restrictArray 规则设置的数组
     * @param userEntity 设置判断人
     * @param type 公海规则子类型 CustomerRuleChildEnum
     * @return
     * 创建时间： 2018-5-29 上午10:59:10
     * 修改时间： 2018-5-29 上午10:59:10 chy
     * @author chy
     * @since v3.22
     * @version v3.22
     */
    public JSONObject getMinObject(JSONArray restrictArray, UserEntity userEntity, Integer type){
        JSONObject allObject = new JSONObject();
        JSONObject specialObject = new JSONObject();
		List<Long> deptIds;
		try {
			deptIds = JSONArray.parseArray(userEntity.getDepartment(), Long.class);
		} catch (Exception e) {
			deptIds = new ArrayList<>();
		}
		if (deptIds == null) {
			deptIds = new ArrayList<>();
		}
		List<Integer> roleIds = new ArrayList<>();
		String role = userEntity.getRoleIds();
		if (StringUtil.isNotEmpty(role)) {
			roleIds = StringUtil.roleIdToListInt(role);
		}
		if (roleIds == null) {
			roleIds = new ArrayList<>();
		}
        for(Object restrictObject : restrictArray){
            JSONObject restrictJson = (JSONObject)restrictObject;
            JSONArray users = restrictJson.getJSONArray("users");
            JSONArray depts = restrictJson.getJSONArray("depts");
            JSONArray roles = restrictJson.getJSONArray("roles");
			List<String> userIdList = new ArrayList<>();
			List<Long> deptIdList = new ArrayList<>();
			List<Integer> roleIdList = new ArrayList<>();
			if (Objects.nonNull(users)) {
				userIdList = JSON.parseArray(users.toJSONString(), String.class);
			}
			if (Objects.nonNull(depts)) {
				deptIdList = JSON.parseArray(depts.toJSONString(), Long.class);
			}
			if (Objects.nonNull(roles)) {
				roleIdList = JSON.parseArray(roles.toJSONString(), Integer.class);
			}
			deptIdList.retainAll(deptIds);
			roleIdList.retainAll(roleIds);
			Boolean scecialConfig = users != null || depts != null || roles != null;
			Boolean configFail = !userIdList.contains(userEntity.getUserId()) && deptIdList.isEmpty() && roleIdList.isEmpty();
			if(scecialConfig && configFail){
				//对于当前用户无效的配置
				continue ;
			}

            JSONArray array = restrictJson.getJSONArray("array");

            if (Objects.equals(type, CustomerRuleChildEnum.CUSTOMER_TYPE.getCode())) {
                stringKey(array, users, depts, roles, allObject, specialObject);
            } else {
                integerKey(array, users, depts, roles, allObject, specialObject);
            }
        }
        return specialObject.isEmpty() ? allObject : specialObject;
    }

    private void stringKey(JSONArray array, JSONArray users, JSONArray depts, JSONArray roles, JSONObject allObject, JSONObject specialObject) {
        for(Object object : array){
            JSONObject jsonObject = (JSONObject)object;
            String key = jsonObject.getString("key");
            Integer value = null;
            try {
				value = jsonObject.getInteger("value");
			}catch (Exception e) {
			}
            if (value == null) {
            	continue;
			}

            if(users == null && depts == null && roles == null){
                allObject.put(key, value);
                continue ;
            }

            //获取所有特殊员工配置的最小值
            Integer minValue = specialObject.getInteger(key);
            //若不存在对应值或值比当前值大，则用当前值覆盖（获取最小值）
            if(minValue == null || minValue > value){
                specialObject.put(key, value);
            }
        }
    }
    private void integerKey(JSONArray array, JSONArray users, JSONArray depts, JSONArray roles, JSONObject allObject, JSONObject specialObject) {
        for(Object object : array){
            JSONObject jsonObject = (JSONObject)object;
            Integer key = jsonObject.getInteger("key");
            Integer value = null;
            try {
				value = jsonObject.getInteger("value");
			} catch (Exception e) {
			}
            if (value == null) {
            	continue;
			}

            if(users == null && depts == null && roles == null){
                allObject.put(key+"", value);
                continue ;
            }

            //获取所有特殊员工配置的最小值
            Integer minValue = specialObject.getInteger(key+"");
            //若不存在对应值或值比当前值大，则用当前值覆盖（获取最小值）
            if(minValue == null || minValue > value){
                specialObject.put(key+"", value);
            }
        }
    }

	/**
	 * 是否是不需要退回的客户
	 * @param customerEntity
	 * @param contract
	 * @param opportunity
	 * @param typeNotIn
	 * @return
	 */
	public boolean notBackCustomer(CustomerEntityExt customerEntity, Integer contract, Integer opportunity, List<String> typeNotIn) {
		Integer type = customerEntity.getData().getInteger(CustomerManagementEnum.TYPE.getAttr());
		String corpid = customerEntity.getCorpid();
		Long customerId = customerEntity.getId();
		//匹配到客户状态
		if (Objects.nonNull(type) && Objects.nonNull(typeNotIn) && typeNotIn.contains(type.toString())) {
			return true;
		}

		if (Objects.isNull(customerId)) {
			return false;
		}
		if (Objects.equals(contract, BasicConstant.ONE)) {
			ContractEntityExt contractEntity = null;
			try {
				contractEntity = contractModel.getLatestEntityByCustomerId(corpid, customerId);
			} catch (XbbException e) {
				e.printStackTrace();
			}
			if (Objects.nonNull(contractEntity)) {
				return true;
			}
		}

		if (Objects.equals(opportunity, BasicConstant.ONE)) {
			OpportunityEntityExt opportunityEntity = null;
			try {
				opportunityEntity = opportunityModel.getLatestEntityByCustomerId(corpid, customerId);
			} catch (XbbException e) {
				e.printStackTrace();
			}
			if (Objects.nonNull(opportunityEntity)) {
				return true;
			}
		}

		return false;
	}
}
